﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics;
using System.Web.Security;
using System.Web.Routing;
using log4net;
using System.Configuration;
using System.Net.NetworkInformation;
using System.Text;
using System.Net;
using System.Data.Objects;
using System.Security.Cryptography;
using System.IO;
using BoardPACUtil.Security;
using BoardPACDSWeb.AuthorizeServiceReference;
using BoardPACDSBO.General;
using BoardPACDSWeb.AnonymousUserServiceReference;
using System.ServiceModel;
using BoardPACDSWeb.UserMgtServiceReference;
using BoardPACUtil.Util;
using BoardPACDSBO.Base;
using BoardPACDSWeb.Lang;


namespace BoardPACDSWeb.Controllers
{
    /// <summary>
    /// 
    ///  <title>Board Paper App</title>
    ///  <description>BaseController for different format redirection</description>
    ///  <copyRight>Copyright (c) 2011</copyRight>
    ///  <company>IronOne Technologies (Pvt)Ltd</company>
    ///  <createdOn>2011-10-18</createdOn>
    ///  <author></author>
    ///  <modification>
    ///     <modifiedBy></modifiedBy>
    ///      <modifiedDate></modifiedDate>
    ///     <description></description>
    ///  </modification>
    ///
    /// </summary>
    public class BaseController : Controller
    {
        protected static ILog EventLog = LogManager.GetLogger("EventLog");
        protected static ILog ErrorLog = LogManager.GetLogger("ErrorLog");

        protected Dictionary<string, string> wcfHeaders = new Dictionary<string, string>();
        HeaderBehavior behavior;

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            try
            {
                //Set data that need to be fetched for each request
                ViewData["UserDisplayName"] = GetLoggedUserDisplayName();
                ViewData["LoginExpiryAlert"] = new LogOnController().AlertLoginExpiry();
                base.OnActionExecuting(filterContext);
            }
            catch (EndpointNotFoundException e)
            {
                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnActionExecuting, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
            }
            catch (Exception e)
            {
                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnActionExecuting, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
            }
        }

        ///OnAuthorization event override
        ///<returns>
        ///true if the role has permission for the invoked action
        ///if false goes to NotAuthorized action
        ///</returns>       
        ///<exception cref="">
        ///
        /// </exception>
        /// <remarks></remarks>
        /*protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            try
            {
                string action = filterContext.ActionDescriptor.ActionName;
                string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                string fmt = GetFormat();

                #region NoAuthorizationNeeded

                if (action.Equals("LogOn")) return;
                if (action.Equals("NotAuthorized")) return;
                if (action.Equals("Error")) return;
                if (action.Equals("InitDeviceXml")) return;
                if (action.Equals("LogOff")) return;
                if (action.Equals("ChangePassword")) return;
                if (action.Equals("Index")) return;

                #endregion NoAuthorizationNeeded

                int Type = Request.QueryString["type"] != null ? int.Parse(Request.QueryString["type"]) : -1;
                int RefId = Request.QueryString["RefId"] != null ? int.Parse(Request.QueryString["RefId"]) : -1;
                if (RefId == 0)
                {
                    RefId = int.Parse((System.Web.HttpContext.Current.Request["SubCategoryId"]));
                }
                if (RefId == -1 && !String.IsNullOrWhiteSpace(System.Web.HttpContext.Current.Request["RefId"]))
                {
                    RefId = int.Parse((System.Web.HttpContext.Current.Request["RefId"]));
                }
                int x = Type;
                int customUserId = GetLoggedUserId();
                bool authorized = false;
                
                //Ping to database?
                //Code changed in order to restrict the navigation of directly entering URL when password expired
                string[] userroles = RoleAuthorizationService.IsAuthorizedOptimized(fmt);
                
                com.IronOne.BoardAppWeb.Models.Entity.aspnet_Roles[] rolesinDB = RoleAuthorizationService.getRolesinDB();
                string actionString = action + "_" + fmt;
                //bool authorized = rolesinDB.Any(y => ((userroles.Contains(y.RoleName)) && (y.Description.Contains(actionString))));
                //-------------------------

                using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {
                    if (!"emptyRole".Equals(userroles.First()))
                    {
                        //String AllowedActions = entities.sp_IsAuthorized(customUserId, Type, RefId, actionString).FirstOrDefault();
                        //if (!String.IsNullOrWhiteSpace(AllowedActions))
                        //{
                        //    authorized = true;
                        //}

                        //adding the allowed action into session
                        ObjectResult<sp_GetRolesinLevels_Result> LevelBasedActions = entities.sp_GetRolesinLevels(customUserId, Type, RefId);
                        RolesByLevel rolesbyLevel = new RolesByLevel();
                        foreach (var item in LevelBasedActions) // This will only run once.
                        {
                            rolesbyLevel.GlobalActions = item.GlobalActions;
                            rolesbyLevel.CategoryActions = item.CategoryActions;
                            rolesbyLevel.SubCategoryActions = item.SubCategoryActions;
                            rolesbyLevel.MeetingActions = item.MeetingActions;
                            rolesbyLevel.PaperActions = item.PaperActions;
                        }

                        RolesByLevel ActionsbyLevel = new RolesByLevel();

                        //Global Level
                        if (!String.IsNullOrWhiteSpace(rolesbyLevel.GlobalActions))
                        {
                            String AllGlobalActionsList = com.IronOne.BoardAppWeb.Lang.ActionsbyLevel.global.ToString();
                            ActionsbyLevel.GlobalActions = FilterActionsByLevel(rolesbyLevel.GlobalActions, AllGlobalActionsList);
                        }

                        //Category Level
                        if (String.IsNullOrWhiteSpace(rolesbyLevel.CategoryActions))
                        {
                            ActionsbyLevel.CategoryActions = rolesbyLevel.GlobalActions;
                        }

                        if (!String.IsNullOrWhiteSpace(rolesbyLevel.CategoryActions))
                        {
                            String AllCategoryActionsList = com.IronOne.BoardAppWeb.Lang.ActionsbyLevel._0.ToString();
                            ActionsbyLevel.CategoryActions = FilterActionsByLevel(rolesbyLevel.CategoryActions, AllCategoryActionsList);
                        }

                        //SubCategory Level
                        if (String.IsNullOrWhiteSpace(rolesbyLevel.SubCategoryActions))
                        {
                            ActionsbyLevel.SubCategoryActions = rolesbyLevel.CategoryActions;
                        }

                        if (!String.IsNullOrWhiteSpace(rolesbyLevel.SubCategoryActions))
                        {
                            String AllSubCategoryActionsList = com.IronOne.BoardAppWeb.Lang.ActionsbyLevel._1.ToString();
                            ActionsbyLevel.SubCategoryActions = FilterActionsByLevel(rolesbyLevel.SubCategoryActions, AllSubCategoryActionsList);                            
                        }

                        //Meeting Level
                        if (String.IsNullOrWhiteSpace(rolesbyLevel.MeetingActions))
                        {
                            ActionsbyLevel.MeetingActions = rolesbyLevel.SubCategoryActions;
                        }

                        if (!String.IsNullOrWhiteSpace(rolesbyLevel.MeetingActions))
                        {
                            String AllMeetingActionsList = com.IronOne.BoardAppWeb.Lang.ActionsbyLevel._2.ToString();
                            ActionsbyLevel.MeetingActions = FilterActionsByLevel(rolesbyLevel.MeetingActions, AllMeetingActionsList);
                        }

                        //Paper Level
                        if (String.IsNullOrWhiteSpace(rolesbyLevel.PaperActions))
                        {
                            ActionsbyLevel.PaperActions = rolesbyLevel.MeetingActions;
                        }

                        if (!String.IsNullOrWhiteSpace(rolesbyLevel.PaperActions))
                        {
                            String AllPaperActionsList = com.IronOne.BoardAppWeb.Lang.ActionsbyLevel._3.ToString();
                            ActionsbyLevel.PaperActions = FilterActionsByLevel(rolesbyLevel.PaperActions, AllPaperActionsList);
                        }

                        Session["ActionsbyLevel"] = ActionsbyLevel;
                        //Global Actions are allowed as it is. Have to check
                        String ActionsAllowedforCurrentUser = ActionsbyLevel.GlobalActions + ActionsbyLevel.CategoryActions + ActionsbyLevel.SubCategoryActions + ActionsbyLevel.MeetingActions + ActionsbyLevel.PaperActions;
                        Session["ActionsAllowedforCurrentUser"] = ActionsAllowedforCurrentUser;

                        if (!String.IsNullOrWhiteSpace(ActionsAllowedforCurrentUser) && ActionsAllowedforCurrentUser.Contains(actionString))
                        {
                            authorized = true;
                        }
                        //-----------------------------
                    }
                    //Have to do like this because EF does not support Scalar Valued UDF
                    //NOTE: EF 5.0 beta1,2 supports tabled valued functions, and may be we can upgrade to this version later
                    //GOTO http://msdn.microsoft.com/en-us/hh859577 OR http://msdn.microsoft.com/en-us/library/gg696190%28v=vs.103%29.aspx for more...
                }
                if (authorized)
                {
                    return;
                }
                else
                {
                   
                    //------------to forward all request to change password interface if password has expired------------
                    if (userroles.First() == "emptyRole")
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "ChangePassword", fmt }));
                        return;
                    }
                    //-------------------------------
                    else
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "NotAuthorized", fmt }));
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnAuthorization, " + User.Identity.Name + "," + e);
            }
        }*/

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            try
            {
                string action = filterContext.ActionDescriptor.ActionName;
                string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                string fmt = GetFormat();
                wcfHeaders.Add(ApplicationConstants.USERNAME, User == null || User.Identity == null ? string.Empty : User.Identity.Name);
                wcfHeaders.Add(ApplicationConstants.ACTION, action);
                wcfHeaders.Add(ApplicationConstants.CONTROLLER, controller);
                wcfHeaders.Add(ApplicationConstants.FORMAT, fmt);
                behavior = new HeaderBehavior(wcfHeaders);

                #region NoAuthorizationNeeded

                if (action.Equals("LogOn")) return;
                if (action.Equals("NotAuthorized")) return;
                if (action.Equals("Error")) return;
                if (action.Equals("InitDeviceXml")) return;
                if (action.Equals("LogOff")) return;
                if (action.Equals("ChangePassword")) return;
                if (action.Equals("Index")) return;
                if (action.Equals("GetHostedVersion")) return;

                #endregion NoAuthorizationNeeded

                int Type = Request.QueryString["type"] != null ? int.Parse(Request.QueryString["type"]) : -1;
                int RefId = Request.QueryString["RefId"] != null ? int.Parse(Request.QueryString["RefId"]) : -1;
                if (RefId == 0)
                {
                    RefId = int.Parse((System.Web.HttpContext.Current.Request["SubCategoryId"]));
                }
                if (RefId == -1 && !String.IsNullOrWhiteSpace(System.Web.HttpContext.Current.Request["RefId"]))
                {
                    RefId = int.Parse((System.Web.HttpContext.Current.Request["RefId"]));
                }
                int x = Type;
                int customUserId = 0;
                try
                {
                    customUserId = GetLoggedUserId();
                }
                catch (Exception)
                {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "LogOn", fmt }));
                    TempData["errMsg"] = "Your session has been expired!";
                    return;
                }
                
                wcfHeaders.Add(ApplicationConstants.USERID, customUserId.ToString());
                wcfHeaders.Add(ApplicationConstants.USERDISPLAYNAME, GetLoggedUserDisplayName());
                behavior = new HeaderBehavior(wcfHeaders);

                //Ping to database?
                /******** Code changed in order to restrict the navigation of directly entering URL when password expired  ************/
                //string[] userroles = RoleAuthorizationService.IsAuthorizedOptimized(fmt);
                //com.IronOne.BoardAppWeb.Models.Entity.aspnet_Roles[] rolesinDB = RoleAuthorizationService.getRolesinDB();
                
                //bool authorized = rolesinDB.Any(y => ((userroles.Contains(y.RoleName)) && (y.Description.Contains(actionString))));
                /*****************************************************************************************/

                string actionString = action + "_" + fmt;
                int PasswordExpiryPeriod = int.Parse(ConfigurationManager.AppSettings["PasswordExpiryPeriod"]);
                
                BaseServiceModel baseServiceModel = new BaseServiceModel();
                using (AuthorizeClient baseClient = new AuthorizeClient())
                {
                    if (!SetCredentials(baseClient))
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "LogOn", fmt }));
                        TempData["errMsg"] = "Your session has been expired!";
                        return;
                    }
                    baseServiceModel = baseClient.OnAuthorization(customUserId, Type, RefId, actionString, PasswordExpiryPeriod, fmt);
                }
                
                Session["ActionsbyLevel"] = baseServiceModel.ActionsbyLevel;
                Session["ActionsAllowedforCurrentUser"] = baseServiceModel.ActionsAllowedforCurrentUser;

                if (baseServiceModel.Authorized)
                {
                    return;
                }
                else
                {
                    /*************to forward all request to change password interface if password has expired********/
                    if (baseServiceModel.userroles.First() == "emptyRole")
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "ChangePassword", fmt }));
                        return;
                    }
                    /**********************************************************/
                    else
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "NotAuthorized", fmt }));
                        return;
                    }
                }
            }
            catch (FaultException<AnonymousUserServiceReference.GenFault> e)
            {
                TempData["errMsg"] = Resources.ResourceManager.GetString(e.Detail.Code);

                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnAuthorization, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Errors", action = "ErrorCustom" }));
                return;
            }
            catch (FaultException e)
            {
                TempData["errMsg"] = Resources.err_801;

                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnAuthorization, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Errors", action = "ErrorCustom" }));
                return;
            }
            catch (EndpointNotFoundException e)
            {
                TempData["errMsg"] = Resources.err_801;

                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnAuthorization, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Errors", action = "ErrorCustom" }));
                return;
            }
            catch (Exception e)
            {
                //TempData["errMsg"] = "Error occurred while authorizing. Please contact the Administrator.";
                TempData["errMsg"] = "Your session has been expired!";
                ErrorLog.Error(EventStatus.Failure.ToString() + ",BaseController" + ", OnAuthorization, " + User.Identity.Name + "," + e.Message + " ," + e.InnerException + " , Source:" + e.Source);
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "LogOn", action = "LogOn" }));
                return;
            }
        }

        protected override void OnException(ExceptionContext filterContext)
        {
            ErrorLog.Error(EventStatus.Failure.ToString() + ", BaseController" + ", OnException, " + User.Identity.Name + "," + filterContext.Exception);
            ModelState.AddModelError("err", new GenException("err_991", filterContext.Exception.Message));
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Base", action = "ErrorView" }));
        }

        ///GetFormatView Action Method
        ///<param name="pageUrl">Location of the view</param>
        ///<param name="model">model</param>
        ///<returns>
        ///Directs to the required view
        ///</returns>       
        ///<exception cref="">
        ///
        /// </exception>
        /// <remarks></remarks>
        public ActionResult GetFormatView(string pageUrl, object model)
        {
            return View("~/Views/" + GetFormat() + "/" + pageUrl, model);
        }

        public ActionResult ErrorView()
        {
            return View("~/Views/Shared/ErrorView.aspx");
        }
        
        ///GetFormatView Action Method
        ///<param name="pageUrl">Location of the view</param>
        ///<returns>
        ///Directs to the required view
        ///</returns>       
        ///<exception cref="">
        ///
        /// </exception>
        /// <remarks>GetFormatView without a model param</remarks>
        ///       
        public ActionResult GetFormatView(string pageUrl)
        {
            return GetFormatView(pageUrl, null);
        }
        
        ///GetFormat return method
        ///<param name="catname">category name</param>
        ///<param name="meetingId">meeting Id</param>
        ///<returns>
        ///Gets fmt value from URL and returns it in uppercase
        ///</returns>       
        ///<exception cref="">
        ///
        /// </exception>
        /// <remarks></remarks>
        /// 
        [NonAction]
        public String GetFormat()
        {
            String fmt = "HTML";

            fmt = Request.Params.Get("fmt");

            if (fmt == null)
            {
                if (Session["fmt"] != null)
                {
                    fmt = Session["fmt"].ToString();
                }
                else
                {
                    fmt = "HTML";
                }
            }
            return fmt.ToUpper();
        }


        ///GetLoggedUserId action method
        ///<returns>
        ///CustomUserId of the logged user
        ///</returns>       
        ///<exception cref="">
        ///Query failed
        /// </exception>
        /// <remarks></remarks>
        /*[NonAction]
        public int GetLoggedUserId()
        {
            if (!User.Identity.IsAuthenticated)
            {
                return 0;
            }

            if (Session["UserId"] == null)
            {
                try
                {
                    using (BoardAppProductEntities boardApp = new BoardAppProductEntities())
                    {
                        // Change this query - can directly get CustomUserId from 'Users' Table by matching UserName. No JOIN Needed.
                        IQueryable<int> x = from us in boardApp.aspnet_Users
                                            where us.UserName == User.Identity.Name
                                            select (us.Users.FirstOrDefault().CustomUserId);

                        return x.FirstOrDefault();
                    }
                }
                catch (Exception e)
                {
                    throw;
                }
            }
            else
            {
                return int.Parse(Session["UserId"].ToString());
            }
        }*/

        public int GetLoggedUserId()
        {
            if (!User.Identity.IsAuthenticated)
            {
                return 0;
            }

            if (Session["UserId"] == null)
            {
                try
                {
                    using (UserMgtServiceClient usrMgt = new UserMgtServiceClient())
                    {
                        SetCredentials(usrMgt);
                        int userId = usrMgt.GetUserCustomId(User.Identity.Name);
                        Session["UserId"] = userId;
                        return userId;
                    }
                }
                catch (FaultException<BoardPACDSWeb.UserMgtServiceReference.GenFault> e)
                {
                    throw;
                }
                catch (FaultException e)
                {
                    throw;
                }
                catch (Exception e)
                {
                    throw;
                }
            }
            else
            {
                return int.Parse(Session["UserId"].ToString());
            }
        }

        /*[NonAction]
        public string GetFNLN()
        {
            if (!User.Identity.IsAuthenticated)
            {
                return null;
            }
            else
            {
                using (BoardAppProductEntities entities = new BoardAppProductEntities())
                {
                    var name = (from u in entities.Users
                                where u.UserName.Equals(User.Identity.Name)
                                select new { u.FirstName, u.LastName }).FirstOrDefault();

                    string firstNameLastName = name.FirstName + " " + name.LastName;
                    return firstNameLastName;
                }
            }
        }*/

        [NonAction]
        public string GetRequestIp()
        {
            return Request.ServerVariables["REMOTE_ADDR"];
        }

        public RequestHeader GetHeaderLogDetails()
        {            
            if (GetFormat() != "XML")
                return null;

            try
            {
                RequestHeader request = new RequestHeader();
                request.action = Request.Headers.GetValues("X-action") != null ? Request.Headers.GetValues("X-action")[0] : null;
                request.clientAppVersion = Request.Headers.GetValues("X-clientAppVersion") != null ? Request.Headers.GetValues("X-clientAppVersion")[0].Trim() : null;
                request.clientTime = Request.Headers.GetValues("X-clientTime") != null ? DateTime.Parse(Request.Headers.GetValues("X-clientTime")[0]) : (DateTime?)null;
                request.cooperateId = Request.Headers.GetValues("X-cooperateId") != null ? int.Parse(Request.Headers.GetValues("X-cooperateId")[0]) : (int?)null;
                request.deviceId = Request.Headers.GetValues("X-deviceId") != null ? Request.Headers.GetValues("X-deviceId")[0] : null;
                request.macAddress = Request.Headers.GetValues("X-macAddress") != null ? Request.Headers.GetValues("X-macAddress")[0] : null;                
                request.requestIp = GetRequestIp();

                return request;
            }
            catch (GenException e)
            {
                throw;
            }
            catch (Exception e)
            {
                ErrorLog.Error("Error " + DateTime.Now + " " + e.Message + e.InnerException + e.StackTrace);
                throw;
            }
        }

        [NonAction]
        public bool PingToDatabase()
        {
            try
            {
                Ping pingSender = new Ping();
                PingOptions options = new PingOptions();

                // Use the default Ttl value which is 128,
                // but change the fragmentation behavior.
                options.DontFragment = true;

                // Create a buffer of 32 bytes of data to be transmitted.
                string data = "Pinging from web server";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeOut = int.Parse(ConfigurationManager.AppSettings["PingTimeOut"].ToString());
                PingReply reply = pingSender.Send(ConfigurationManager.AppSettings["DatabaseIP"].ToString().Trim(), timeOut, buffer, options);

                if (reply.Status != IPStatus.Success)
                    throw new GenException("err_150");
            }
            catch (Exception)
            {
                throw;
            }

            return true;
        }

        //currently not being used.
        /*public bool hierachicalAuthorize(int RefId, int x, int customUserId, String actionString, string[] userroles)
        {
            bool authorized = false;
            com.IronOne.BoardAppWeb.Models.Entity.aspnet_Roles[] rolesinDB = RoleAuthorizationService.getRolesinDB();

            using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
            {
                if (RefId >= 0)
                {
                    while (x >= 0)
                    {
                        Access access = entities.Accesses.Where(a => (a.CustomUserId == customUserId && a.Type == x && a.RefId == RefId)).FirstOrDefault();

                        //For the Next iteration, have to change the RefId
                        if (access == null)
                        {
                            if (x == 3)
                            {
                                RefId = (from p in entities.Papers
                                         where p.PaperId == RefId
                                         select p.Heading.MeetingId).FirstOrDefault();
                            }
                            else if (x == 2)
                            {
                                RefId = (from m in entities.Meetings
                                         where m.MeetingId == RefId
                                         select m.SubCategoryId).FirstOrDefault();
                            }
                            else if (x == 1)
                            {
                                RefId = (from s in entities.SubCategories
                                         where s.SubCategoryId == RefId
                                         select s.CategoryId).FirstOrDefault();
                            }
                        }
                        else if (access != null)
                        {
                            System.Guid roleId = access.RoleId;
                            if (rolesinDB.Any(r => ((r.RoleId == roleId) && (r.Description.Contains(actionString)))))
                            {
                                return true;
                            }
                            else
                            {
                                authorized = false;
                                break;
                            }
                        }
                        x--;
                    }
                }

                if (x == -1)
                {
                    authorized = rolesinDB.Any(y => ((userroles.Contains(y.RoleName)) && (y.Description.Contains(actionString))));
                }
            }
            return authorized;
        }*/

        /*public RolesByLevel GetRolesforLevels(int type, int refId)
        {
            try
            {
                using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {
                    ObjectResult<sp_GetRolesinLevels_Result> LevelBasedActions = entities.sp_GetRolesinLevels(GetLoggedUserId(), type, refId);
                    RolesByLevel rolesbyLevel = new RolesByLevel();
                    foreach (var item in LevelBasedActions)
                    {
                        rolesbyLevel.GlobalActions = item.GlobalActions;
                        rolesbyLevel.CategoryActions = item.CategoryActions;
                        rolesbyLevel.SubCategoryActions = item.SubCategoryActions;
                        rolesbyLevel.MeetingActions = item.MeetingActions;
                        rolesbyLevel.PaperActions = item.PaperActions;
                    }

                    return rolesbyLevel;
                }
            }
            catch (Exception e)
            {
                EventLog.Info("120, " + "ERR, " + EventStatus.Failure.ToString() + ", Base" + ", GetRolesforLevels," + User.Identity.Name + "," + com.IronOne.BoardAppWeb.Lang.Resources.err_120);
                ErrorLog.Info("120, " + "ERR, " + EventStatus.Failure.ToString() + ", Base" + ", GetRolesforLevels," + User.Identity.Name + ", " + e.Message);
                ModelState.AddModelError("err", new GenException("err_120"));
                return null;
            }
            //write finally and add 
        }*/
        
        /*public bool IsAccessible1(String ActionName)
        {
            RolesByLevel ActionsbyLevel = new RolesByLevel();

            if (Session["AllowedActions"] != null)
            {
                ActionsbyLevel = (RolesByLevel)Session["ActionsbyLevel"];
            }
            else
            {
                ActionsbyLevel.CategoryActions = "Dummy"; //TODO: Get Actions from DB.
                ActionsbyLevel.SubCategoryActions = "Dummy";
                ActionsbyLevel.MeetingActions = "Dummy";
                ActionsbyLevel.PaperActions = "Dummy";
            }


            if (ActionsbyLevel.CategoryActions.Contains(ActionName))
            {
                return true;
            }

            if (ActionsbyLevel.SubCategoryActions.Contains(ActionName))
            {
                return true;
            }

            if (ActionsbyLevel.MeetingActions.Contains(ActionName))
            {
                return true;
            }
            
            if (ActionsbyLevel.PaperActions.Contains(ActionName))
            {
                return true;
            }
            else
            {
                return false;
            }
        }*/

        public String FilterActionsByLevel(String LevelActions, String AllActions)
        {
            List<String> LevelActionsList = LevelActions.Split(',').ToList();
            List<String> LevelAllActionsList = AllActions.Split(',').ToList();
            //List<String> Difference = LevelActionsList.Except(LevelAllActionsList).ToList();
            //Difference = LevelActionsList.Except(Difference).ToList();
            List<String> Similarity = LevelActionsList.Intersect(LevelAllActionsList).ToList();

            String temp = String.Empty;

            foreach (var item in Similarity)
            {
                temp = temp + item + ", ";
            }
            return temp;
        }

        public bool IsAccessible(String AllActions, String ActionName)
        {
            if (AllActions.Contains(ActionName))
            {
                return true;
            }

            return false;
        }

        [NonAction]
        public string GetLoggedUserDisplayName()
        {
            if (!User.Identity.IsAuthenticated)
            {
                return string.Empty;
            }

            if (Session["UserDisplayName"] == null)
            {
                try
                {
                    using (UserMgtServiceClient usrMgt = new UserMgtServiceClient())
                    {
                        SetCredentials(usrMgt);
                        string displayName = usrMgt.GetUserDisplayName(User.Identity.Name);
                        Session["UserDisplayName"] = displayName;
                        return displayName;
                    }
                }
                catch (FaultException<BoardPACDSWeb.UserMgtServiceReference.GenFault> e)
                {
                    throw;
                }
                catch (FaultException e)
                {
                    throw;
                }
                catch (Exception e)
                {
                    throw;
                }
            }
            else
            {
                return Session["UserDisplayName"].ToString();
            }
        }

        #region Set Credentials for WCF Service

        protected const string key = "gWv$+6f1@.`=g96";
        protected const string saltKey = "x4@5^tBv$+6f1@";
        protected const string VIKey = "@1B2c3D4e5F6g7H8";

        public static string EncryptText(string userName, string password)
        {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(password);

            byte[] keyBytes = new Rfc2898DeriveBytes(userName + key, Encoding.ASCII.GetBytes(saltKey)).GetBytes(256 / 8);
            var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
            var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

            byte[] cipherTextBytes;

            using (var memoryStream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                    cryptoStream.FlushFinalBlock();
                    cipherTextBytes = memoryStream.ToArray();
                    cryptoStream.Close();
                }
                memoryStream.Close();
            }
            return Convert.ToBase64String(cipherTextBytes);
        }

        public static string DecryptText(string userName, string encryptedText)
        {
            byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
            byte[] keyBytes = new Rfc2898DeriveBytes(userName + key, Encoding.ASCII.GetBytes(saltKey)).GetBytes(256 / 8);
            var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };

            var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
            var memoryStream = new MemoryStream(cipherTextBytes);
            var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];

            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
        }

        internal void SetCredentials(string userName, string password)
        {
            Session["passwdHash"] = EncryptText(userName.Trim(), password);
        }

        internal string GetCredentials()
        {
            if (Session["passwdHash"] != null)
            {
                string passwordHash = Session["passwdHash"].ToString();
                return DecryptText(User.Identity.Name, passwordHash);
            }
            else
            {
                FormsAuthentication.SignOut();
                Session.Abandon();
                return String.Empty;
            }
        }


        [NonAction]
        protected bool SetCredentials(AuthorizeClient client)
        {
            client.ClientCredentials.UserName.UserName = User.Identity.Name;
            string pass = GetCredentials();
            if (string.IsNullOrEmpty(pass))
            {
                return false;
            }
            else
            {
                client.ClientCredentials.UserName.Password = pass;
                client.Endpoint.Behaviors.Add(behavior);
                return true;
            }
        }

        [NonAction]
        protected void SetCredentials(AnonymousUserServiceClient client)
        {
            client.Endpoint.Behaviors.Add(behavior);
        }

        [NonAction]
        protected bool SetCredentials(UserMgtServiceClient client)
        {
            client.ClientCredentials.UserName.UserName = User.Identity.Name;
            string pass = GetCredentials();
            if (string.IsNullOrEmpty(pass))
            {
                return false;
            }
            else
            {
                client.ClientCredentials.UserName.Password = pass;
                client.Endpoint.Behaviors.Add(behavior);
                return true;
            }
        }
        
        #endregion
    }
}
